package com.rockcent.api.controller;

import com.rockcent.api.Routes;
import com.rockcent.common.common.JsonResult;
import com.rockcent.common.common.PageResult;
import com.rockcent.common.common.RestDoing;
import com.rockcent.common.controller.BaseController;
import com.rockcent.common.domain.enumclass.Whether;
import com.rockcent.common.utils.RBeanUtils;
import com.rockcent.mall.lib.domain.*;
import com.rockcent.mall.lib.dto.UserAdminDto;
import com.rockcent.mall.lib.dto.UserInfoDto;
import com.rockcent.mall.lib.helper.BaseUserHelper;
import com.rockcent.mall.lib.repository.*;
import com.rockcent.service.AuthUserResourceSrv;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * Created by oyhk on 2017/3/9.
 *
 * R端用户管理
 */
@RestController
@RequestMapping(value = Routes.API_VERSION)
public class SSOAdminController extends BaseController {

    private final Logger log = LoggerFactory.getLogger(SSOAdminController.class);

    @Autowired
    private UserAdminRepository userAdminRepository;
    @Autowired
    private UserInfoRepository userInfoRepository;
    @Autowired
    private AuthUserResourceRepository authUserResourceRepository;
    @Autowired
    private AuthTitleResourceRepository authTitleResourceRepository;
    @Autowired
    private AuthTitleRepository authTitleRepository;
    @Autowired
    private AuthResourceRepository authResourceRepository;
    @Autowired
    private AuthUserResourceSrv authUserResourceSrv;
    @Autowired
    private BaseUserHelper userHelper;

    /**
     * @api {get} /v1/sso/user_admin/page R端用户 分页
     * @apiGroup SSO-USER-ADMIN
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     *
     * @apiParam {long} titleId 菜单id
     *
     * @apiSuccess {long} id 主ID
     * @apiSuccess {long} userId 用户ID
     * @apiSuccess {String} userAccount 账户名
     * @apiSuccess {String} name 使用者
     * @apiSuccess {String} titleName 职称名称
     * @apiSuccess {long} titleId 职称Id
     * @apiSuccess {String} isSuperAdmin 是否超级管理员
     * @apiSuccess {String=YES("启用"), NO("停止")} available 是否启用
     *
     * @apiSuccessExample {json} Success-Response:
     * {
     *   "code": "1",
     *   "desc": "成功",
     *   "data": {
     *      "data": [
     *          {
     *              "id": 1,
     *              "dateCreated": "2017-03-09 18:04:57",
     *              "lastUpdated": "2017-03-09 18:06:07",
     *              "version": 0,
     *              "userId": 545,
     *              "userAccount": "13450286811",
     *              "titleName": "网管",
     *              "name": "超级管理员",
     *              "isSuperAdmin": "YES",
     *              "available": "YES"
     *          }
     *      ],
     *      "totalCount": 1,
     *      "totalPage": 1,
     *      "pageNo": 0,
     *      "pageSize": 10,
     *      "url": "/sso/user_admin/page",
     *      "prevUrl": "/sso/user_admin/page?pageNo=0&pageSize=10",
     *      "nextUrl": "/sso/user_admin/page?pageNo=0&pageSize=10"
     *   }
     * }
     */
    @RequestMapping(value = Routes.SSO_USER_ADMIN_PAGE, method = RequestMethod.GET)
    public JsonResult page(Integer pageNo, Integer pageSize, Long titleId, HttpServletRequest request) {
        RestDoing doing = jsonResult -> {
            PageResult<UserAdmin> pageResult = userAdminRepository.findUserAdminPage(titleId, this.getPage(pageNo, pageSize));
            pageResult.setUrl(Routes.SSO_USER_ADMIN_PAGE);
            jsonResult.data = pageResult;
        };
        return doing.go(request, log);
    }

    /**
     * @api {get} /v1/sso/user_admin/info R端用户 详情
     * @apiGroup SSO-USER-ADMIN
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     *
     * @apiParam {long} id <code>必传参数</code> 主id
     *
     * @apiSuccess {long} id 主ID
     * @apiSuccess {long} userId 用户ID
     * @apiSuccess {String} userAccount 账户名
     * @apiSuccess {String} name 使用者
     * @apiSuccess {long} titleId 职称Id
     * @apiSuccess {String} isSuperAdmin 是否超级管理员
     *
     * @apiSuccessExample {json} Success-Response:
     * {
     *   "code": "1",
     *   "desc": "成功",
     *   "data": {
     *      "data":
     *          {
     *              "id": 1,
     *              "dateCreated": "2017-03-09 18:04:57",
     *              "lastUpdated": "2017-03-09 18:06:07",
     *              "version": 0,
     *              "userId": 545,
     *              "titleId": 545,
     *              "userAccount": "13450286811",
     *              "name": "超级管理员",
     *              "isSuperAdmin": "YES",
     *              "resourceIdList" : [1,2,3,4]
     *          }
     *   }
     * }
     */
    @RequestMapping(value = Routes.SSO_USER_ADMIN_INFO, method = RequestMethod.GET)
    public JsonResult info(HttpServletRequest request, UserAdminDto userAdminDto) {
        RestDoing doing = jsonResult -> {
            Long id = userAdminDto.getId();
            if (id == null) {
                jsonResult.errorParam(UserAdmin.CHECK_ID_IS_NOT_NULL,log);;
                return;
            }
            UserAdmin userAdmin = userAdminRepository.findOne(id);
            if (userAdmin == null) {
                jsonResult.remind(UserAdmin.REMIND_RECORD_IS_NOT_EXIST,log);;
                return;
            }
//            Long titleId = userAdmin.getTitleId();
            List<AuthUserResource> authUserResourceList = authUserResourceRepository.findByUserAdminId(id);

//            List<AuthTitleResource> authTitleResourceList = authTitleResourceRepository.findByTitleId(titleId);
//            List<Long> resourceIdList = authTitleResourceList.stream().map(AuthTitleResource::getResourceId).collect(Collectors.toList());
            List<Long> resourceIdList = authUserResourceList.stream().map(AuthUserResource::getResourceId).collect(Collectors.toList());
            RBeanUtils.copyProperties(userAdmin, userAdminDto);
            userAdminDto.setResourceIdList(resourceIdList);
            jsonResult.data = userAdminDto;
        };
        return doing.go(request, log);
    }

    /**
     * @api {post} /v1/sso/user_admin/invite R端用户 邀请
     * @apiGroup SSO-USER-ADMIN
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     *
     *
     * @apiParam {String} username <code>必传参数</code> 用户账号
     * @apiParam {String} name <code>必传参数</code> 名称
     * @apiParam {Long} titleId  <code>必传参数</code>职称id
     *
     * @apiSuccessExample {json} Success-Response:
     * {
     *   "code": "1",
     *   "desc": "成功"
     * }
     */
    @Transactional
    @RequestMapping(value = Routes.SSO_USER_ADMIN_INVITE, method = RequestMethod.POST)
    public JsonResult invite(@RequestBody UserAdminDto userAdminDto, HttpServletRequest request) {
        RestDoing doing = jsonResult -> {
            if (StringUtils.isBlank(userAdminDto.getUsername())) {
                jsonResult.errorParam(UserInfo.CHECK_USERNAME_IS_NOT_NULL,log);
                return;
            }
            Long titleId = userAdminDto.getTitleId();
            if (titleId == null) {
                jsonResult.errorParam("职称id不能为空",log);
                return;
            }
            AuthTitle authTitle = authTitleRepository.findOne(titleId);
            if (authTitle == null) {
                jsonResult.remind("职称不存在",log);
                return;
            }
            UserInfo userInfo = userInfoRepository.findByUsername(userAdminDto.getUsername());
            if (userInfo == null) {
                jsonResult.remind("账户名不存在,请先注册",log);
                return;
            }
            UserAdmin userAdmin = userAdminRepository.findByUserId(userInfo.getId());
            if (userAdmin != null) {
                jsonResult.remind("此用户已经邀请过了",log);
                return;
            }
            // 保存邀请用户
            userAdmin = new UserAdmin();
            String userAdminDtoName = userAdminDto.getName();
            userAdmin.setName(userAdminDtoName);
            userAdmin.setUserId(userInfo.getId());
            userAdmin.setTitleName(authTitle.getName());
            userAdmin.setUsername(userInfo.getUsername());
            userAdmin.setTitleId(authTitle.getId());
            userAdmin = userAdminRepository.save(userAdmin);

            Long adminId = userAdmin.getId();

            // 查询职称权限列表
            List<AuthTitleResource> authTitleResourceList = authTitleResourceRepository.findByTitleId(titleId);

            authUserResourceSrv.batchSave(authTitleResourceList, userInfo.getId(), adminId);

        };
        return doing.go(request, log);
    }

    /**
     * @api {put} /v1/sso/user_admin/update R端用户 更改
     * @apiGroup SSO-USER-ADMIN
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     *
     *
     * @apiParam {Long} titleId <code>必传参数</code> 职称id
     * @apiParam {Long} id <code>必传参数</code> 主ID
     * @apiParam {String} username <code>必传参数</code> 账号
     * @apiParam {String} name <code>必传参数</code> 使用者
     * @apiParam {Long} resourceIdList  菜单ID集合 例如:[1,2,3]
     *
     * @apiSuccessExample {json} Success-Response:
     * {
     *   "code": "1",
     *   "desc": "成功"
     * }
     */
    @Transactional
    @RequestMapping(value = Routes.SSO_USER_ADMIN_UPDATE, method = RequestMethod.PUT)
    public JsonResult update(@RequestBody UserAdminDto userAdminDto, HttpServletRequest request) {
        RestDoing doing = jsonResult -> {
            String username = userAdminDto.getUsername();
            if (StringUtils.isBlank(username)) {
                jsonResult.errorParam(UserInfo.CHECK_USERNAME_IS_NOT_NULL,log);
            }
            if (StringUtils.isBlank(userAdminDto.getName())) {
                jsonResult.remind("使用者 不能为空",log);
                return;
            }
            if (StringUtils.isBlank(userAdminDto.getUsername())) {
                jsonResult.remind("账号 不能为空",log);
                return;
            }
            if (userAdminDto.getId() == null) {
                jsonResult.errorParam(UserAdmin.CHECK_ID_IS_NOT_NULL,log);;
                return;
            }
            Long titleId = userAdminDto.getTitleId();
            if (titleId == null) {
                jsonResult.errorParam("职称id不能为空",log);
                return;
            }
            AuthTitle authTitle = authTitleRepository.findOne(titleId);
            if (authTitle == null) {
                jsonResult.remind("职称不存在",log);
                return;
            }
            UserInfo userInfo = userInfoRepository.findByUsername(username);
            if (userInfo == null) {
                jsonResult.remind(UserInfo.REMIND_RECORD_IS_NOT_EXIST,log);;
                return;
            }

            Long userId = userInfo.getId();
            UserAdmin userAdmin = userAdminRepository.findByUserId(userId);
            if (userAdmin == null) {
                jsonResult.remind("此修改用户不存在",log);
                return;
            }

            // 删除用户资源权限
            List<AuthUserResource> authUserResourceList = authUserResourceRepository.findByUserAdminId(userAdmin.getId());
            authUserResourceRepository.delete(authUserResourceList);

            userAdmin.setName(userAdminDto.getName());
            // 当改变角色时，所有权限重新设置
//            if (!userAdmin.getTitleId().equals(authTitle.getId())) {
                userAdmin.setTitleId(authTitle.getId());
                userAdmin.setTitleName(authTitle.getName());
                // 重新设置
                //List<AuthTitleResource> authTitleResourceList = authTitleResourceRepository.findByTitleId(titleId);
                //authUserResourceSrv.batchSave(authTitleResourceList, userInfo.getId(), userAdmin.getId());
                userAdminRepository.save(userAdmin);
//            }
            //保存用户权限
            List<Long> resourceIdList = userAdminDto.getResourceIdList();
            if (resourceIdList != null && resourceIdList.size() > 0) {
                for (Long resourceId : resourceIdList) {
                    AuthUserResource authUserResource = new AuthUserResource();
                    authUserResource.setUserId(userId);
                    authUserResource.setResourceId(resourceId);
                    AuthResource authResource = authResourceRepository.findOne(resourceId);
                    if (authResource != null && authResource.getParentId() != null) {
                        authUserResource.setResourceParentId(authResource.getParentId());
                    }
                    authUserResource.setUserAdminId(userAdmin.getId());
                    authUserResourceRepository.save(authUserResource);
                }
            }

        };
        return doing.go(request, log);
    }

    /**
     * @api {put} /v1/sso/user_admin/delete R端用户 删除
     * @apiGroup SSO-USER-ADMIN
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     *
     *
     * @apiParam {Long} id <code>必传参数</code> R端用户id
     *
     * @apiSuccessExample {json} Success-Resp：：onse:
     * {
     *   "code": "1",
     *   "desc": "成功"
     * }
     */
    @RequestMapping(value = Routes.SSO_USER_ADMIN_DELETE, method = RequestMethod.PUT)
    public JsonResult delete(@RequestBody UserAdminDto userAdminDto, HttpServletRequest request) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (userAdminDto.getId() == null) {
                jsonResult.errorParam(UserAdmin.CHECK_ID_IS_NOT_NULL,log);;
                return;
            }

            UserAdmin userAdmin = userAdminRepository.findOne(userAdminDto.getId());
            if (userAdmin == null) {
                jsonResult.remind(UserAdmin.REMIND_RECORD_IS_NOT_EXIST,log);;
                return;
            }
            if (Objects.equals(userInfoDto.getId(), userAdmin.getUserId())) {
                jsonResult.remind("不能对自己账号进行删除操作",log);
                return;
            }
            if (userAdmin.getIsSuperAdmin() == Whether.YES) {
                jsonResult.remind("不能删除超级管理员",log);
                return;
            }
            // 删除用户资源
            List<AuthUserResource> authUserResourceList = authUserResourceRepository.findByUserAdminId(userAdmin.getId());
            authUserResourceRepository.delete(authUserResourceList);
            // 删除用户
            userAdminRepository.delete(userAdmin);

        };
        return doing.go(request, log);
    }

    /**
     * @api {put} /v1/sso/user_admin/update_available 启动,停止
     * @apiGroup SSO-USER-ADMIN
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     *
     *
     * @apiParam {Long} id <code>必传参数</code> R端用户id
     * @apiParam {String=YES("启用"), NO("停止")} available <code>必传参数</code> 是否启用
     *
     * @apiSuccessExample {json} Success-Response:
     * {
     *   "code": "1",
     *   "desc": "成功"
     * }
     */
    @RequestMapping(value = Routes.SSO_USER_ADMIN_UPDATE_AVAILABLE, method = RequestMethod.PUT)
    public JsonResult updateAvailable(@RequestBody UserAdminDto userAdminDto, HttpServletRequest request) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (userAdminDto.getId() == null) {
                jsonResult.remind(UserAdmin.CHECK_ID_IS_NOT_NULL,log);;
                return;
            }
            if (StringUtils.isBlank(userAdminDto.getAvailable().toString()) || !EnumUtils.isValidEnum(Whether.class, userAdminDto.getAvailable().toString())) {
                jsonResult.remind("是否启用 只允许YES(\"启用\"), NO(\"停止\")",log);
                return;
            }
            UserAdmin userAdmin = userAdminRepository.findOne(userAdminDto.getId());
            if (userAdmin == null) {
                jsonResult.remind(UserAdmin.REMIND_RECORD_IS_NOT_EXIST,log);;
                return;
            }
            if (Objects.equals(userInfoDto.getId(), userAdmin.getUserId())) {
                jsonResult.remind("不能对自己账号进行停止或者启动操作",log);
                return;
            }
            if (userAdmin.getIsSuperAdmin() == Whether.YES) {
                jsonResult.remind("不能对超级管理员进行停止或者启动操作",log);
                return;
            }
            userAdmin.setAvailable(userAdminDto.getAvailable());
            userAdminRepository.save(userAdmin);
        };
        return doing.go(request, log);
    }
}
